package com.quxian.chambercommerce.pagination;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.quxian.chambercommerce.searchCondition.CommonSearchBean;
import com.quxian.chambercommerce.util.StringUtil;

public class PaginationList
{
	private CommonSearchBean searchBean;
	private int dataSize;
	private List<Object> dataList;
	
	private String queryUrl;
	
	private Map<String, Object> paramMap;
	
	public List<Object> getDataList()
	{
		return dataList;
	}
	
	public int getDataSize()
	{
		return dataSize;
	}
	
	private PaginationList()
	{
		paramMap = new HashMap<String, Object>();
	}
	
	public void addParam(String key, Object val)
	{
		if(StringUtil.isEmpty(key) || val == null)
		{
			return;
		}
		paramMap.put(key, val);
	}
	
	public static PaginationList createPaginationList(List dataList, CommonSearchBean searchBean)
	{
		PaginationList pagination = new PaginationList();
		pagination.dataList = dataList;
		pagination.searchBean = searchBean;
		pagination.queryUrl = ServletActionContext.getRequest().getRequestURI().toString();
		if(dataList != null)
		{
			pagination.dataSize = dataList.size();
		}
		ActionContext.getContext().put("result", pagination);
		return pagination;
	}
	
	public String getPagination()
	{
		if(searchBean == null)
		{
			return null;
		}
		
		StringBuilder builder = new StringBuilder(500);
		builder.append(getSearchForm());
		builder.append(getJavaScript());
		builder.append(getPaginationItemList());
		return builder.toString();
	}
	
	private String getSearchForm()
	{
		StringBuilder builder = new StringBuilder(150);
		builder.append("<form id=\"pagination_search_form\" method=\"POST\" action=\"").append(queryUrl).append("\">");
		if(searchBean != null && !StringUtil.isEmpty(searchBean.getKeyword()))
		{
			builder.append("<input type=\"hidden\" name=\"searchBean.keyword\" value=\"").append(searchBean.getKeyword()).append("\"/>");
		}
		if(paramMap != null && paramMap.size() > 0)
		{
			for(Map.Entry<String, Object> entry : paramMap.entrySet())
			{
				if(entry != null)
				{
					builder.append("<input type=\"hidden\" name=\"").append(entry.getKey()).append("\" value=\"").append(entry.getValue()).append("\"/>");
				}
			}
		}
		builder.append("<input id=\"searchBean_pageNo\" type=\"hidden\" name=\"searchBean.pageNo\" value=\"\"/>");
		builder.append("</form>");
		return builder.toString();
	}
	
	private String getJavaScript()
	{
		StringBuilder builder = new StringBuilder(100);
		builder.append("<script type=\"text/javascript\">");
		builder.append("function toPage(pageNo)");
		builder.append("{");
		builder.append("$('#searchBean_pageNo').val(pageNo);");
		builder.append("$('#pagination_search_form').submit();");
		builder.append("}");
		builder.append("</script>");
		return builder.toString();
	}
	
	private String getPaginationItemList()
	{
		if(searchBean == null)
		{
			return null;
		}
		StringBuilder builder = new StringBuilder(250);
		builder.append(generateItemLink(searchBean.getPageNo() - 1, "<"));
		builder.append(generateItemLink(1));
		
		if(searchBean.getPageNo() - 1 > 4)
		{
			builder.append("<span>...</span>");
			for(int i = (searchBean.getPageNo() - 4); i <= searchBean.getPageNo(); i++)
			{
				builder.append(generateItemLink(i));
			}
		}
		else
		{
			for(int i = 2; i <= searchBean.getPageNo(); i++)
			{
				builder.append(generateItemLink(i));
			}
		}
		
		if(lastPageNo() - searchBean.getPageNo() > 4)
		{
			for(int i = (searchBean.getPageNo() + 1); i <= (searchBean.getPageNo() + 5); i++)
			{
				builder.append(generateItemLink(i));
			}
			builder.append("<span>...</span>");
		}
		else
		{
			for(int i = (searchBean.getPageNo() + 1); i < lastPageNo(); i++)
			{
				builder.append(generateItemLink(i));
			}
		}
		
		builder.append(generateItemLink(lastPageNo()));
		builder.append(generateItemLink(searchBean.getPageNo() + 1, ">"));
		return builder.toString();
	}
	
	private String generateItemLink(int pageNo)
	{
		return generateItemLink(pageNo, null);
	}
	
	private String generateItemLink(int pageNo, String label)
	{
		label = StringUtil.isEmpty(label) ? pageNo + "" : label;
		StringBuilder builder = new StringBuilder(50);
		if(pageNo == searchBean.getPageNo() || pageNo <= 0 || pageNo > lastPageNo())
		{
			builder.append("<span class='currentPageNo'>").append(label).append("</span>");
		}
		else
		{
			builder.append("<a class='clickablePageNo' click='#' href='javascript:toPage(").append(pageNo).append(");'>").append(label).append("</a>");
		}
		return builder.toString();
	}
	
	private int lastPageNo()
	{
		int no = searchBean.getTotalCount() / searchBean.getPageSize();
		if(searchBean.getTotalCount() % searchBean.getPageSize() == 0)
		{
			return no;
		}
		return no + 1;
	}
	
	private boolean hasPrefPage()
	{
		return searchBean.getPageNo() != 1;
	}
	
	private boolean hasNextPage()
	{
		return searchBean.getPageNo() != lastPageNo();
	}
}